package com.specdot.kraster.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JFrame;

import com.specdot.kraster.core.FragmentInput;
import com.specdot.kraster.core.FragmentShader;
import com.specdot.kraster.core.Mesh;
import com.specdot.kraster.core.Rasterizer;
import com.specdot.kraster.core.RenderJob;
import com.specdot.kraster.core.VertexInput;
import com.specdot.kraster.core.VertexOutput;
import com.specdot.kraster.core.VertexShader;
import com.specdot.kraster.math.Dir3;
import com.specdot.kraster.math.Matrix4x4;
import com.specdot.kraster.math.Point3;
import com.specdot.kraster.math.Vector4;

public class MainWindow extends JFrame {
	private RenderFrame renderFrame;
	private RenderJob job = new RenderJob();
	private Rasterizer rasterizer = new Rasterizer();
	
	public MainWindow() {
		setLayout(new BorderLayout());
		setMinimumSize(new Dimension(800, 600));
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		
		renderFrame = new RenderFrame();
		renderFrame.setOnFrameRenderHandler(new OnFrameRenderHandler() {
			@Override
			public void handle(int width, int height, Graphics g) {
				onRender(width, height, g);
			}
		});
		
		add(renderFrame);
		
		setupJob();
	}
	
	private void setupJob() {
		job.fragmentShader = new FragmentShader() {
			@Override
			public Vector4 invoke(FragmentInput fin) {
				return null;
			}
		};
		
		job.meshData = new Mesh();
		job.meshData.positions = new Point3[] {
			new Point3(-0.5f, 0f, 5f),
			new Point3(0.5f, 0f, 5f),
			new Point3(0, 0.5f, 5f),
		};
		
		job.meshData.indices = new int[] {0, 1, 2};
	
		Matrix4x4 proj = Matrix4x4.perspective(1, 100, 30, 3f / 4f);
		Matrix4x4 view = Matrix4x4.lookAt(new Point3(0, 0, 0), new Dir3(0, 1, 0), new Dir3(0, 1, 0));
		
		job.vertexShader = new VertexShader() {
			
			@Override
			public VertexOutput invoke(VertexInput vin) {
				VertexOutput vout = new VertexOutput();
				
				vout.pos = proj.mutiplyVector4(view.mutiplyVector4(vin.pos));
				
				return vout;
			}
		};
	}
	
	private void onRender(int width, int height, Graphics g) {
		job.targetScreen = new GraphicsScreen(height, width, g);
		rasterizer.render(job);
	}
}
